﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
using Util;

namespace UtilEditors
{
    public class GUILayoutCom
    {
        public static GUILayoutOption[] GUIs = new GUILayoutOption[] {
         GUILayout.Width(100),
         GUILayout.Height(20),
        };
        public GameObject[] SelectionObj => Selection.gameObjects;



        public virtual void OnGUI()
        {

        }
        public static bool Button(string com)
        {
            return GUILayout.Button(com,GUIs);
        }
        public static bool Button(string com,params GUILayoutOption[] gs)
        {
            return GUILayout.Button(com,gs);
        }
        public static void EnumPopup(Enum com)
        {
            EditorGUILayout.EnumPopup(com,GUIs);
        }

        public static void Toggle(string com,ref bool isTogg,bool isWidth = false)
        {
            if(isWidth)
            {
                isTogg = GUILayout.Toggle(isTogg,com,GUILayout.MaxWidth(com.Length * 4 + 20));
            }
            else
            {
                isTogg = GUILayout.Toggle(isTogg,com);
            }
        }

        public static void ToggleLeft(string com,ref bool isTogg,bool isWidth = false)
        {
            if(isWidth)
            {
                isTogg = EditorGUILayout.ToggleLeft(com,isTogg,GUILayout.MaxWidth(com.Length * 4 + 20));
            }
            else
            {
                isTogg = EditorGUILayout.ToggleLeft(com,isTogg);
            }
        }

        public static bool ToggleLeft(string com,bool isTogg,bool isWidth = false)
        {
            if(isWidth)
            {
                return EditorGUILayout.ToggleLeft(com,isTogg,GUILayout.MaxWidth(com.Length * 4 + 20));
            }
            return EditorGUILayout.ToggleLeft(com,isTogg);
        }

        //...水平布局
        public static void StrX(params GUILayoutOption[] options) { GUILayout.BeginHorizontal(options); }

        public static void EndX()
        {
            GUILayout.EndHorizontal();
        }

        //...垂直布局
        public static void StrY() { GUILayout.BeginVertical(); }

        public static void EndY()
        {
            GUILayout.EndVertical();
        }

        public static void ComX(Action action,params GUILayoutOption[] options)
        {
            GUILayout.BeginHorizontal(options);
            action.toInvoke();
            GUILayout.EndHorizontal();
        }
        //区域
        public static void Area(Rect rect,Action action)
        {
            GUILayout.BeginArea(rect);
            action.toInvoke();
            GUILayout.EndArea();
        }
        static GUIStyle badge;//黑色边框
        public static GUIStyle Badge { get { if(badge.isNull()) { badge = GUI.skin.FindStyle("Badge"); } return badge; } }
        public static void ComY(Action action,params GUILayoutOption[] options)
        {
            GUILayout.BeginVertical(Badge,options);
            action.toInvoke();
            GUILayout.EndVertical();
        }
        //进度条
        /// <summary>
        /// 当前的类容, 当前ID, 最大数量
        /// </summary>
        /// <param name="action"></param>
        public static void ProgressBar(Action<Action<string,int,int>> action)
        {
            action((title,cur,max) =>
            {
                EditorUtility.DisplayProgressBar(string.Format("{0}/{1}",cur,max),title,cur.toFloat() / max);
            });
            EditorUtility.ClearProgressBar();
        }

        //隔间
        public static void Space(int w = 20)
        {
            EditorGUILayout.Space(w);
        }

        //检测变化
        public static void ChangeCheck(Action tf,Action Ex)
        {
            EditorGUI.BeginChangeCheck();
            tf.toInvoke();
            if(EditorGUI.EndChangeCheck())
            {
                Ex.toInvoke();
            }
        }

        public static void Text(string Com)
        {
            if(Com.Length == 0)
            {
                return;
            }
            EditorGUILayout.LabelField(Com,GUILayout.MaxWidth(Com.Length * 13));
        }

        public static void Inpt(string Name,ref int v,bool x = true)
        {
            if(x)
                StrX(GUILayout.MaxWidth(100));
            Text(Name);
            v = EditorGUILayout.IntField(v);
            if(x)
                EndX();
        }

        public static void Inpt(string Name,ref float v,bool x = true)
        {
            if(x)
                StrX(GUILayout.MaxWidth(100));
            Text(Name);
            v = EditorGUILayout.FloatField(v);
            if(x)
                EndX();
        }

        public static void Inpt(string Name,ref Vector3 v,bool x = true)
        {
            Text(Name);
            v = EditorGUILayout.Vector3Field("",v,GUILayout.MaxWidth(100));
        }

        public static void Inpt(string Name,ref bool v,bool x = true)
        {
            v = GUILayout.Toggle(v,Name);
        }

        public static void Inpt(string Name,ref Vector2 v,bool x = true)
        {
            Text(Name);
            v = EditorGUILayout.Vector2Field("",v,GUILayout.MaxWidth(100));
        }

        public static void Inpt(string Name,ref string v,bool x = true)
        {
            if(x)
                StrX();
            Text(Name);
            v = EditorGUILayout.TextField(v);
            if(x)
                EndX();
        }

        /// <summary>
        /// 获取路径
        /// </summary>
        public static void FilePanel(string title,ref string path)
        {
            //获得一个长300的框
            EditorGUILayout.LabelField("选文件夹.对象: " + title);
            EditorGUILayout.LabelField(string.Format("路径:{0}",path));

            GUILayout.BeginHorizontal();
            Rect rect = EditorGUILayout.GetControlRect(/*GUILayout.Width(position.width - 160)*/);//创建GUILayout的EditorGUI大小

            Object mObj = AssetDatabase.LoadAssetAtPath<Object>(path);
            if(mObj.isTrue())
            {
                EditorGUILayout.ObjectField(mObj,typeof(Object),true,GUILayout.MaxWidth(100));
            }
            if(GUILayout.Button("选择",GUILayout.MaxWidth(60)))
            {
                path = EditorUtility.OpenFilePanel("选择文件","","");
                path = path.toUintyPath();
            }
            GUILayout.EndHorizontal();

            //将上面的框作为文本输入框
            path = EditorGUI.TextField(rect,path);

            //如果鼠标正在拖拽中或拖拽结束时，并且鼠标所在位置在文本输入框内
            if((//Event.current.type == EventType.DragUpdated ||
               Event.current.type == EventType.DragExited) &&
               rect.Contains(Event.current.mousePosition))
            {
                //改变鼠标的外表
                DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                if(DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
                {
                    path = DragAndDrop.paths[0];
                }
            }
            else
            if((Event.current.type == EventType.DragUpdated //||
              /*Event.current.type == EventType.DragExited*/) &&
              rect.Contains(Event.current.mousePosition))
            {
                //改变鼠标的外表
                DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
            }
        }

        public static void InptComponent<T>(string Name,ref T v) where T : Component
        {
            StrX();
            Text(Name);
            v = EditorGUILayout.ObjectField(v,typeof(T),true) as T;
            EndX();
        }

        public static void InptObj<T>(string Name,ref T v,bool x = true) where T : Object
        {
            if(x)
                StrX();
            Text(Name);
            v = EditorGUILayout.ObjectField(v,typeof(T),true,GUILayout.MaxWidth(100)) as T;
            if(x)
                EndX();
        }

        public static void InptObj<T>(ref T v) where T : Object
        {
            v = EditorGUILayout.ObjectField(v,typeof(T),true,GUILayout.MaxWidth(100)) as T;
        }
        public static void Inpt<T>(string Name,ref T v,bool x = true) where T : Object
        {
            if(x)
                StrX();
            Text(Name);
            v = EditorGUILayout.ObjectField(v,typeof(T),true,GUILayout.MaxWidth(100)) as T;
            if(x)
                EndX();
        }

        public static void Inpt<T>(string Name,ref List<T> com) where T : Object
        {
            if(com == null)
            {
                com = new List<T>();
            }
            StrX();
            Text(Name);
            if(Button("获取",GUILayout.Width(35),GUILayout.Height(15)))
            {
                for(int i = 0; i < Selection.objects.Length; i++)
                {
                    var obj = (T)Selection.objects[i];
                    com.Add(obj);
                }
            }
            EndX();
            int num = com.Count;
            Inpt("Size",ref num);
            while(num != com.Count)
            {
                if(num > com.Count)
                {
                    com.Add(null);
                }
                else
                {
                    com.RemoveAt(com.Count - 1);
                }
            }
            for(int i = 0; i < com.Count; i++)
            {
                var v = com[i];
                v = EditorGUILayout.ObjectField(v,typeof(T),true,GUILayout.MaxWidth(100)) as T;
                com[i] = v;
            }
        }
        //拖选文件夹,对象,获取文件夹下全部对象
        public static void DragSelect<T>(DragSelectData<T> data) where T : Object
        {
            DragSelect(data.title,ref data.path,ref data.All,ref data.IsFoldout);
        }

        //拖选文件夹,对象,获取文件夹下全部对象
        public static void DragSelect<T>(string title,ref string path,ref List<T> All,ref bool IsFoldout) where T : Object
        {
            for(int i = All.Count - 1; i > 0; i--)
            {
                if(!All[i])
                {
                    All.RemoveAt(i);
                }
            }
            string cpath = path;
            FilePanel(title,ref path);
            if(!path.Contains("."))
            {
                if(!path.Equals(cpath))
                {
                    UtilEditor.FindPathAllFile(path,ref All);
                }
                IsFoldout = EditorGUILayout.Foldout(IsFoldout,"折叠:" + All.Count.toString());
                if(IsFoldout)
                {
                    for(int i = 0; i < All.Count; i++)
                    {
                        GUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField((i + 1).toString() + ":",GUILayout.MaxWidth(20));
                        All[i] = EditorGUILayout.ObjectField(All[i],typeof(T),true) as T;
                        GUILayout.EndHorizontal();
                    }
                }
            }
        }

        /// <summary>
        /// 显示列表
        /// </summary>
        /// <param name="titile"></param>
        /// <param name="isShow"></param>
        /// <param name="list"></param>
        public static void ShowList(string titile,ref bool isShow,List<Object> list)
        {

            isShow = EditorGUILayout.Foldout(isShow,string.Format("{0}:{1}",titile,list.Count));
            if(isShow)
            {
                for(int i = 0; i < list.Count; i++)
                {
                    list[i] = EditorGUILayout.ObjectField(list[i],typeof(Object),true);
                }
            }
        }

    }

    public class BaseEditorWindow :EditorWindow
    {
        public static GUILayoutOption[] GUIs = new GUILayoutOption[] {
         GUILayout.Width(100),
         GUILayout.Height(20),
        };

        public GUILayoutCom mainMenu;
        public virtual void Awake()
        {
            Repaint();
        }

        public static BaseEditorWindow rfe;

        //快捷键  把 # % & 组合使用吧。#代表Shift，%代表Ctrl，&代表Alt。
        //[MenuItem("Tools/辅助/GameWindow %&F12")]==> Ctrl + Alt + F12
        public static void Init<T>() where T : BaseEditorWindow
        {
            rfe = (T)EditorWindow.GetWindow(typeof(T));
            rfe.Show();
        }
        public virtual void InitData()
        {

        }

        public virtual void OnGUI()
        {
            mainMenu.OnGUI();
        }

        public virtual void OnEnable()
        {
            mainMenu = new GUILayoutCom();
        }

        public virtual void OnFocus()
        {
            //Debug.Log("当窗口获得焦点时调用一次");
        }

        public virtual void OnLostFocus()
        {
            // Debug.Log("当窗口丢失焦点时调用一次");
        }

        public virtual void OnHierarchyChange()
        {
            //Debug.Log("当Hierarchy视图中的任何对象发生改变时调用一次");
        }

        public virtual void OnProjectChange()
        {
            //Debug.Log("当Project视图中的资源发生改变时调用一次");
        }

        //选择其他对象
        public virtual void OnSelectionChange() { }

    }
}